Whenever data is shared between suppliers of data and consumers of the supplied data, challenges may arise because the providers and the consumers do not provide and consume at the same rate. One challenge that may arise is consuming data that changes while it is being consumed. Ignoring the fact that the underlying data has changed could result in errors because incongruous or incoherent states of the data may have been consumed. Reacting to every change could force the consumer to do unnecessary or time-consuming computation, which may be incompatible with the responsiveness demands of the application. Locking the underlying data when a coherent data state is needed by the consumer could result in deadlock. Not locking the underlying data could require complex consumer code to handle the universe of changes that might occur or necessitate the production of expensive copies of the data.